-
Notifications
You must be signed in to change notification settings - Fork 2
Docs: V0.2-tutorials/consistent linear system example #129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds a "Tutorials" section to the documentation, specifically including a least squares example that demonstrates how to use the RLinearAlgebra.jl package's SparseSign compression method. The purpose is to provide hands-on examples for new users to quickly understand the package usage.
- Adds a complete tutorials framework with introduction and getting started guides
- Creates a comprehensive least squares solving example using SparseSign compression
- Adds development documentation including style guides, contributing guidelines, and checklists
Reviewed Changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Compressors/sparse_sign.jl | Fixes typo in documentation comment |
| readme.md | Comments out Aqua QA badge |
| docs/src/tutorials/ | Adds new tutorial section with introduction and getting started guide |
| docs/src/manual/introduction.md | Adds comprehensive manual introduction to randomized linear algebra |
| docs/src/dev/ | Adds development documentation including style guide, design docs, and contributing checklists |
| docs/make.jl | Updates documentation structure and deployment configuration |
| .github/workflows/ | Adds new CI/CD workflows for automated version management and documentation |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think removing Dev Docs from this PR and splitting up the tutorials into increasingly more customized pieces would be a better approach.
docs/src/tutorials/introduction.md
Outdated
| # Introduction | ||
|
|
||
| The purpose of these tutorials is to use examples help | ||
| new users quickly get hands on the usage of `RLinearAlgebra.jl`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| new users quickly get hands on the usage of `RLinearAlgebra.jl`. | |
| new users quickly get hands experience using `RLinearAlgebra.jl`. |
docs/src/tutorials/introduction.md
Outdated
| ## How tutorials are structured | ||
|
|
||
| Problem sets: | ||
| - Least squre problem, solving $$\min_{x} \|Ax - b\|_2^2$$ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| - Least squre problem, solving $$\min_{x} \|Ax - b\|_2^2$$ | |
| - Least squares problem, solving $$\min_{x} \|Ax - b\|_2^2$$ |
docs/make.jl
Outdated
| deploydocs( | ||
| repo = "github.com/numlinalg/RLinearAlgebra.jl" | ||
| repo = "github.com/numlinalg/RLinearAlgebra.jl", | ||
| devbranch = "master", # master's newest commit will become dev |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be "main"
docs/make.jl
Outdated
| "Home" => "index.md", | ||
| "Tutorials" => [ | ||
| "Introduction" => "tutorials/introduction.md", | ||
| "Least square" => "tutorials/least_square.md" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| "Least square" => "tutorials/least_square.md" | |
| "Least squares" => "tutorials/least_square.md" |
|
|
||
| $$\min_{x} \|Ax - b\|_2^2$$ | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we are looking at a consistent linear system in this example, I think we should not present the least squares formulation.
|
|
||
| * **Matrix `A`**: A random $1000 \times 20$ matrix. | ||
| * **Vector `b`**: Calculated as $b = A x_{\text{true}}$, with dimensions $1000 \times 1$. | ||
| * **Goal**: Find a solution $x$ that is as close as possible to $x_{\text{true}}$. | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would remove this. The previous sentence explains things well.
|
|
||
| ```@example SparseSignExample | ||
| # Import relevant libraries | ||
| using RLinearAlgebra, Random, LinearAlgebra |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you do not need Random
| # Solving a Consistent Linear System | ||
|
|
||
| This guide demonstrates how to use `RLinearAlgebra.jl` package to solve a | ||
| **consistent linear system**—a system where at least one solution |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- --> ---
|
|
||
| This guide demonstrates how to use `RLinearAlgebra.jl` package to solve a | ||
| **consistent linear system**—a system where at least one solution | ||
| exists—expressed in the form: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
---> ---
| **consistent linear system**—a system where at least one solution | ||
| exists—expressed in the form: | ||
|
|
||
| $$Ax = b$$ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs a punctuation mark at the end of the equation.
| --- | ||
| ## Problem setup and solve the system | ||
|
|
||
| First, let's define our linear system $Ax = b$. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| First, let's define our linear system $Ax = b$. | |
| First, let's define our linear system $Ax = b$ with some known solution `x_true`. |
|
|
||
| To easily verify the accuracy of our solver, we'll construct a problem where the true | ||
| solution, $x_{\text{true}}$, is known beforehand. We'll start by creating a random | ||
| matrix $A$ and a known solution vector $x_{\text{true}}$. Then, we can generate the | ||
| right-hand side vector $b$ by computing $b = Ax_{\text{true}}$. | ||
|
|
||
| The following Julia code imports the necessary libraries, sets up the dimensions, and | ||
| creates $A$, $x_{\text{true}}$, and $b$. We also initialize a starting guess, `x_init`, | ||
| for our iterative solver. | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can remove this.
| logger = BasicLogger(max_it = 300) | ||
| kaczmarz_solver = Kaczmarz(log = logger) | ||
| solver_recipe = complete_solver(kaczmarz_solver, x_init, A, b) | ||
| rsolve!(solver_recipe, x_init, A, b) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| rsolve!(solver_recipe, x_init, A, b) | |
| rsolve!(solver, solution, A, b) |
| solution = x_init; | ||
| println("Solution to the system: \n", solution) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would remove these
| solution = x_init; | ||
| println("Solution to the system: \n", solution) | ||
| ``` | ||
| **Done! How simple it is!** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"rsolve! puts the solution in the vector solution.
| --- | ||
| ## Problem setup and solve the system |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this
| Let's check how close our calculated `solution` is to the known `x_true`. | ||
| We can measure the accuracy by calculating the Euclidean norm of the difference | ||
| between the two vectors. A small norm indicates that our solver found a good approximation. | ||
|
|
||
| ```@example ConsistentExample | ||
| # Calculate the norm of the error | ||
| error_norm = norm(solution - x_true) | ||
| println(" - Norm of the error between the solution and x_true: ", error_norm) | ||
| ``` | ||
| As you can see, by using the modular Kaczmarz solver, we were able to configure a | ||
| randomized block-based method and find a solution vector that is very close to | ||
| the true solution. | ||
|
|
||
|
|
||
| Let's break down the solver code line by line to understand what each part does. | ||
|
|
||
| --- | ||
| ## Codes breakdown | ||
|
|
||
| As shown in the code, we used the [`Kaczmarz` solver](@ref Kaczmarz). A key feature of | ||
| **RLinearAlgebra.jl** is its modularity; you can customize the solver's behavior by passing | ||
| in different "component" objects for tasks, such as system compression, progress logging, | ||
| and termination checks. | ||
|
|
||
| For this example, we kept it simple by only customizing the maximum iteration located | ||
| in [`Logger`](@ref Logger) component. Let's break down each step. | ||
|
|
||
|
|
||
| ### Configure the logger | ||
|
|
||
| We start with the simplest component: the [`Logger`](@ref Logger). The | ||
| [`Logger`](@ref Logger) is | ||
| responsible for tracking metrics (such as the error history) and telling the solver | ||
| when to stop. For this guide, we use the default [`BasicLogger`](@ref BasicLogger) | ||
| and configure | ||
| it with a single stopping criterion: a maximum number of iterations. | ||
|
|
||
| ```julia | ||
| # Configure the maximum iteration to be 300 | ||
| logger = BasicLogger(max_it = 300) | ||
| ``` | ||
|
|
||
| ### Create the solver | ||
|
|
||
| Before running the solver on our specific problem (`A, b, x_init`), we must prepare it | ||
| using the [`complete_solver`](@ref complete_solver) function. This function creates | ||
| a [`KaczmarzRecipe`](@ref KaczmarzRecipe), which combines the solver | ||
| configuration with the problem data. | ||
|
|
||
| Crucially, this "recipe" pre-allocates all necessary memory buffers, which is a | ||
| key step for ensuring efficient and high-performance computation. | ||
|
|
||
| ```julia | ||
| # Create the Kaczmarz solver object by passing in the ingredients | ||
| kaczmarz_solver = Kaczmarz(log = logger) | ||
| # Create the solver recipe by combining the solver and the problem data | ||
| solver_recipe = complete_solver(kaczmarz_solver, x_init, A, b) | ||
| ``` | ||
|
|
||
| ### Solve the system using the solver | ||
|
|
||
| Finally, we call [`rsolve!`](@ref rsolve!) to execute the algorithm. The `!` at the end | ||
| of the function name is a Julia convention indicating that the function will inplace | ||
| update part of its arguments. In this case, `rsolve!` modifies `x_init` in-place, | ||
| filling it with the final solution vector. The solver will iterate until a stopping | ||
| criterion in the `logger` is met, i.e. iteration goes up to $300$. | ||
|
|
||
| ```julia | ||
| # Run the inplace solver! | ||
| rsolve!(solver_recipe, x_init, A, b) | ||
|
|
||
| # The solution is now stored in the updated x_init vector | ||
| solution = x_init; | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can go somewhere else.
Description
Docs:
RLinearAlgebra.jlto solve typical linear algebra problems.tutorials/introduction.mdtutorials/consistent_systemfolder.Fix:
BasicLoggerlogging logic.Motivation and Context
Refer to the JuMP.jl Tutorials section.
How has this been tested
First, download the
RLinearAlgebra.jlto your local Julia environment.Then, open Julia in the folder of
RLinearAlgebra.jl, and use the following codes to see the document:Types of changes
Checklists:
Code and Comments
If this PR includes modification to the code base, please select all that apply.
API Documentation
Manual Documentation
Testing
@code_lowered and
@code_typed)